package com.hdl.school.utils;

import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hdl.school.application.MyApplication;
import com.hdl.school.bean.ClassInfo;
import com.hdl.school.bean.CourseInfo;
import com.hdl.school.bean.RoomEventAction;
import com.hdl.school.bean.SignInInfo;
import com.hdl.school.bean.StudentInfo;
import com.hdl.school.bean.TeacherInfo;
import com.hdl.school.listener.OnCardEventListener;
import com.leectrl.utils.Bus;
import com.leectrl.utils.DbUtil;
import com.leectrl.utils.HexUtil;

import org.xutils.db.sqlite.SqlInfo;
import org.xutils.db.table.DbModel;
import org.xutils.ex.DbException;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class CardReaderManager {
    private static CardReaderManager cardReaderManager;
    private OnCardEventListener onCardEventListener;
    private long lastCodeTime = 0;
    private String cardNum = "";
    //当前老师卡号
    private String currentCardNum = null;
    private long lastUsbCardReceiceTime = 0;

    //默认一卡通认证模式
    private String checkMode="all";
    private JSONArray schedule;
    private JSONObject cardReaderConfig;

    //今日课程
    private List<CourseInfo> todayCourses = new ArrayList<>();
    Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    checkCard((String) msg.obj);
                    break;
                case 2:
                    checkCard((String) msg.obj);
                    break;
                case 1:
                    checkSignInCard((String) msg.obj);
                    break;
            }
        }
    };

    public JSONArray getSchedule() {
        return schedule;
    }

    public void setSchedule(JSONArray schedule) {
        this.schedule = schedule;
    }

    public String getCheckMode() {
        return checkMode;
    }

    public void setCheckMode(String checkMode) {
        this.checkMode = checkMode;
    }

    public void setScheduleData(JSONObject scheduleData) {
        //获取考勤设置
        JSONObject signSetting = scheduleData.getJSONObject("sign_setting");
        if (signSetting.getBooleanValue("enable") == false) {
            return;
        }
        Date date = new Date();
        int week = date.getDay();
        if (week == 0) {
            week = 7;
        }
        String todayStr = TimeUtil.date2String(date, "yyyy-MM-dd");
        if (scheduleData.containsKey("calendarData")) {
            JSONArray calendarData = scheduleData.getJSONArray("calendarData");
            if (calendarData != null && calendarData.size() > 0) {
                for (int i = 0; i < calendarData.size(); i++) {
                    JSONObject jsonObject = calendarData.getJSONObject(i);
                    if (jsonObject.getString("yd").equals(todayStr)) {
                        int refWeek = jsonObject.getIntValue("ref_week");
                        if (refWeek > 0) {
                            week = refWeek;
                        }
                    }
                }
            }
        }

        //获取当前节次
        JSONObject termInfo = scheduleData.getJSONObject("term");
        JSONArray classTimes = termInfo.getJSONArray("classes");
        JSONArray signDur = signSetting.getJSONArray("dur");
        int signTimeStart = signDur.getIntValue(0);
        int signTimeEnd = signDur.getIntValue(1);

        //获取当前是第几周

        String startDateStr = termInfo.getString("start_date");
        Date startDate = TimeUtil.string2Date(startDateStr + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
        int startDay = startDate.getDay();
        if (startDay == 0) {
            startDay = 7;
        }
        long monDateTime = startDate.getTime() - (startDay - 1) * 24 * 3600000;
        int currentWeeks = (int) ((date.getTime() - monDateTime) / (24 * 3600000)) + 1;
        JSONArray courseData = scheduleData.getJSONArray("scheduleData");
        todayCourses.clear();
        for (int j = 0; j < courseData.size(); j++) {
            JSONObject courseItem = courseData.getJSONObject(j);
            if (courseItem.getIntValue("week_day") != week) {
                continue;
            }
            int scheduleId = courseItem.getIntValue("id");
            for (int k = 0; k < classTimes.size(); k++) {
                JSONObject classTime = classTimes.getJSONObject(k);
                if (classTime.getIntValue("class_id") == courseItem.getIntValue("class_id")) {
                    long classStart = TimeUtil.timeInToday(classTime.getString("start_time"));
                    long classEnd = TimeUtil.timeInToday(classTime.getString("end_time"));
                    long signStart = classStart + signTimeStart * 60000;
                    long signEnd = classStart + signTimeEnd * 60000;
                    String coursesStr = courseItem.getString("class_info");
                    if (coursesStr != null && coursesStr.length() > 0 && coursesStr.startsWith("[")) {
                        JSONArray courseItems = JSONArray.parseArray(coursesStr);
                        for (int m = 0; m < courseItems.size(); m++) {
                            JSONObject courseObj = courseItems.getJSONObject(m);
                            int weekTag = courseObj.getIntValue("weekTag");
                            if (weekTag == 0 || (currentWeeks % 2 == weekTag % 2)) {
                                CourseInfo courseInfo = new CourseInfo();
                                courseInfo.setScheduleId(scheduleId);
                                courseInfo.setName(courseObj.getString("course_name"));
                                courseInfo.setCourseId(courseObj.getIntValue("course_id"));
                                courseInfo.setStartTime(classStart);
                                courseInfo.setEndTime(classEnd);
                                courseInfo.setSignStart(signStart);
                                courseInfo.setSignEnd(signEnd);
                                JSONObject teacherObj = JSON.parseObject(courseObj.getString("teacher"));
                                TeacherInfo teacherInfo = new TeacherInfo();
                                teacherInfo.setTeacherName(teacherObj.getString("teacher_name"));
                                teacherInfo.setWorkCode(teacherObj.getString("work_code"));
                                courseInfo.setTeacherInfo(teacherInfo);
                                List<ClassInfo> classInfoList = new ArrayList<>();
                                JSONArray classes = JSON.parseArray(courseObj.getString("classes"));
                                for (int l = 0; l < classes.size(); l++) {
                                    JSONObject classObj = classes.getJSONObject(l);
                                    ClassInfo classInfo = new ClassInfo();
                                    classInfo.setClassId(classObj.getIntValue("class_id"));
                                    classInfo.setClassName(classObj.getString("class_name"));
                                    classInfoList.add(classInfo);
                                }
                                courseInfo.setClassInfoList(classInfoList);
                                todayCourses.add(courseInfo);
                            }
                        }
                    }
                    break;
                }
            }
        }
        Log.e("courseInfo", JSON.toJSONString(todayCourses));
    }

    private CardReaderManager() {

        Bus.getInstance().on("receive_serial_code", new Bus.MessageEvent() {
            @Override
            public void onEvent(String key, Object... message) {
                String mPortType = (String) message[1];
                String code = ((String) message[2]).toLowerCase();
                if ("cardreader".equals(mPortType)) {
                    if (code.equals("fe010300ec56b17bebffff")) {
                        //拔卡
                        if (currentCardNum != null) {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("card_num", currentCardNum);
                            Bus.getInstance().emit("scene_event", "pull_card", jsonObject);
                            currentCardNum = null;
                            Bus.getInstance().emit("pull_card");
                        }

                    } else if (code.indexOf("fe010300ec56") == 0 && code.length() >= 30) {
                        String cardHex = code.substring(14, 22);
                        StringBuffer cardBuffer = new StringBuffer();
                        for (int i = 3; i >= 0; i--) {
                            cardBuffer.append(cardHex.substring(2 * i, 2 * (i + 1)));
                        }
                        Message message1 = new Message();
                        message1.what = 0;
                        message1.obj = StringUtil.padNum(Long.parseLong(cardBuffer.toString(), 16), 10);
                        handler.sendMessage(message1);
                    } else {
                        System.out.println("qr:" + code);
                        if (code.endsWith("0d0a")) {
                            String text = HexUtil.hexToText(code.substring(0, code.length() - 4));
                            System.out.println("qr:" + text);
                            if (text.length() == 10) {
                                //IC卡
                                Message message1 = new Message();
                                message1.what = 0;
                                message1.obj = text;
                                handler.sendMessage(message1);
                            } else {
                                //二维码

                            }
                        }

                    }

                } else if ("attendancereader".equals(mPortType)) {
                    //签到
                    if (code.indexOf("fe010300ec56") == 0 && code.length() >= 30) {
                        String cardHex = code.substring(14, 22);
                        StringBuffer cardBuffer = new StringBuffer();
                        for (int i = 3; i >= 0; i--) {
                            cardBuffer.append(cardHex.substring(2 * i, 2 * (i + 1)));
                        }
                        Message message1 = new Message();
                        message1.what = 1;
                        message1.obj = StringUtil.padNum(Long.parseLong(cardBuffer.toString(), 16), 10);
                        handler.sendMessage(message1);
                    }
                }
            }
        });

    }

    public void clearCurrentCard() {
        currentCardNum = null;
    }

    public static CardReaderManager getInstance() {
        if (cardReaderManager == null) {
            cardReaderManager = new CardReaderManager();
        }
        return cardReaderManager;
    }


    public void setOnCardEventListener(OnCardEventListener onCardEventListener) {
        this.onCardEventListener = onCardEventListener;

    }


    public void onKeyCode(int keyCode) {
        Log.d("CardReaderManager", "keyCode:" + keyCode);
        if (keyCode == 66) {
            Log.d("CardReaderManager", "读取到" + cardNum);
            cardNum = StringUtil.padNum(cardNum, 10);
            long now = System.currentTimeMillis();
            if (now - lastUsbCardReceiceTime < 5000) {
                if (CardReaderManager.this.onCardEventListener != null) {
                    CardReaderManager.this.onCardEventListener.onCardReaderBusy(5 - (int) ((now - lastUsbCardReceiceTime) / 1000));
                }
            } else {
                lastUsbCardReceiceTime = now;
                if (this.onCardEventListener != null&&cardNum.length()==10) {
                    this.onCardEventListener.onReceiveCard(cardNum);
                }
                Message message1 = new Message();
                message1.what = 2;
                message1.obj = cardNum;
                handler.sendMessage(message1);
            }
            cardNum = "";
            lastCodeTime = 0;
        } else {
            long now = System.currentTimeMillis();
            String code = parseKeyName(keyCode);
            if (code != null) {
                if (lastCodeTime > 0) {
                    if (now - lastCodeTime < 1000) {
                        cardNum += code;
                    }
                } else {
                    cardNum += code;
                }
                lastCodeTime = now;
            } else {
                cardNum = "";
            }
        }
    }


    public void checkCard(String cn) {
        final String checkCard = cn;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    SharedPreferences sharedPreferences= MyApplication.myApplication.getSharedPreferences("school_iot",0);
                    String cardReaderSetting=sharedPreferences.getString("c_setting_cardReaderMode",null);
                    if(cardReaderSetting!=null){
                        cardReaderConfig=JSON.parseObject(cardReaderSetting);
                        if(cardReaderConfig.containsKey("card_mode")){
                            checkMode=cardReaderConfig.getString("card_mode");
                        }
                    }

                    //liuyong 限制时间段内才能刷卡
                    /*Calendar calendar = Calendar.getInstance();
                    int hour = calendar.get(Calendar.HOUR_OF_DAY);

                    if (hour >= 9 && hour < 21) {
                        // 当前时间在2点到6点之间
                        if("all".equals(checkMode)){
                            currentCardNum = checkCard;
                            if (CardReaderManager.this.onCardEventListener != null) {
                                CardReaderManager.this.onCardEventListener.onCardCheckSuccess(checkCard);
                            }
                            if(cardReaderConfig!=null&&cardReaderConfig.getBoolean("auto_inclass_enable")){
                                USBSerialManager.getInstence().sendSerialMessageFromPort(null,true,"CEECFFFDDDDD0001010000DDDDDF".toLowerCase());
                            }
                            Bus.getInstance().emit("slot_card");
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("card_num", currentCardNum);
                            jsonObject.put("checked", currentCardNum != null);
                            Bus.getInstance().emit("scene_event", "slot_card", jsonObject);

                        }else if("card".equals(checkMode)){
                            DbModel model = DbUtil.getInstance().findDbModelFirst(new SqlInfo("select id,name from card_info where card_num='" + checkCard + "' and delete_tag=0"));
                            if (model != null) {
                                //教职工刷卡开设备
                                currentCardNum = checkCard;
                                if (CardReaderManager.this.onCardEventListener != null) {
                                    CardReaderManager.this.onCardEventListener.onCardCheckSuccess(checkCard);
                                }
                                if(cardReaderConfig!=null&&cardReaderConfig.getBoolean("auto_inclass_enable")){
                                    USBSerialManager.getInstence().sendSerialMessageFromPort(null,true,"CEECFFFDDDDD0001010000DDDDDF".toLowerCase());
                                }
                                Bus.getInstance().emit("slot_card");
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put("card_num", currentCardNum);
                                jsonObject.put("checked", currentCardNum != null);
                                Bus.getInstance().emit("scene_event", "slot_card", jsonObject);
                            } else {
                                currentCardNum = null;
                                if (CardReaderManager.this.onCardEventListener != null) {
                                    CardReaderManager.this.onCardEventListener.onCardCheckFailure(checkCard);
                                }
                            }

                        }

                        RoomEventAction roomEventAction = new RoomEventAction();
                        roomEventAction.setAction("card_brush");
                        roomEventAction.setCardNum(checkCard);
                        roomEventAction.setEventTime(TimeUtil.getCurTimeToDate());
                        roomEventAction.setUoloadTag(0);
                        roomEventAction.setAuthResult(currentCardNum != null ? 1 : 0);
                        roomEventAction.setTag(TimeUtil.currentStap() + "" + (int) (Math.random() * 1000));
                        DbUtil.getInstance().save(roomEventAction);

                    } else {
                        //liuyong
                        // 当前时间不在2点到4点之间
                        // 播音播报不在刷卡时间内

                        currentCardNum = checkCard;
                        if (CardReaderManager.this.onCardEventListener != null) {
                            CardReaderManager.this.onCardEventListener.onCardReaderLimit(checkCard);
                        }

                    }

                } catch (DbException e) {
                    e.printStackTrace();
                    currentCardNum = null;
                    if (CardReaderManager.this.onCardEventListener != null) {
                        CardReaderManager.this.onCardEventListener.onCardCheckFailure(checkCard);
                    }
                }
            }
        }).start();
        */
                    if("all".equals(checkMode)){
                        currentCardNum = checkCard;
                        if (CardReaderManager.this.onCardEventListener != null) {
                            CardReaderManager.this.onCardEventListener.onCardCheckSuccess(checkCard);
                        }
                        if(cardReaderConfig!=null&&cardReaderConfig.getBoolean("auto_inclass_enable")){
                            USBSerialManager.getInstence().sendSerialMessageFromPort(null,true,"CEECFFFDDDDD0001010000DDDDDF".toLowerCase());
                        }
                        Bus.getInstance().emit("slot_card");
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("card_num", currentCardNum);
                        jsonObject.put("checked", currentCardNum != null);
                        Bus.getInstance().emit("scene_event", "slot_card", jsonObject);

                    }else if("card".equals(checkMode)){
                        DbModel model = DbUtil.getInstance().findDbModelFirst(new SqlInfo("select id,name from card_info where card_num='" + checkCard + "' and delete_tag=0"));
                        if (model != null) {
                            //教职工刷卡开设备
                            currentCardNum = checkCard;
                            if (CardReaderManager.this.onCardEventListener != null) {
                                CardReaderManager.this.onCardEventListener.onCardCheckSuccess(checkCard);
                            }
                            if(cardReaderConfig!=null&&cardReaderConfig.getBoolean("auto_inclass_enable")){
                                USBSerialManager.getInstence().sendSerialMessageFromPort(null,true,"CEECFFFDDDDD0001010000DDDDDF".toLowerCase());
                            }

                            Bus.getInstance().emit("slot_card");
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("card_num", currentCardNum);
                            jsonObject.put("checked", currentCardNum != null);
                            Bus.getInstance().emit("scene_event", "slot_card", jsonObject);
                        } else {
                            currentCardNum = null;
                            if (CardReaderManager.this.onCardEventListener != null) {
                                CardReaderManager.this.onCardEventListener.onCardCheckFailure(checkCard);
                            }
                        }

                    }

                    RoomEventAction roomEventAction = new RoomEventAction();
                    roomEventAction.setAction("card_brush");
                    roomEventAction.setCardNum(checkCard);
                    roomEventAction.setEventTime(TimeUtil.getCurTimeToDate());
                    roomEventAction.setUoloadTag(0);
                    roomEventAction.setAuthResult(currentCardNum != null ? 1 : 0);
                    roomEventAction.setTag(TimeUtil.currentStap() + "" + (int) (Math.random() * 1000));
                    DbUtil.getInstance().save(roomEventAction);
                } catch (DbException e) {
                    e.printStackTrace();
                    currentCardNum = null;
                    if (CardReaderManager.this.onCardEventListener != null) {
                        CardReaderManager.this.onCardEventListener.onCardCheckFailure(checkCard);
                    }
                }
            }
        }).start();
    }

    private void checkSignInCard(String cn) {
        final String checkCard = cn;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    StudentInfo studentInfo = DbUtil.getInstance().selector(StudentInfo.class).where("card_num", "=", checkCard).findFirst();
                    if (studentInfo != null) {
                        int classId = studentInfo.getClassId();
                        long now = System.currentTimeMillis();
                        //查询当前课程信息
                        synchronized (todayCourses) {
                            int signTag = -1;
                            for (CourseInfo courseInfo : todayCourses) {
                                if (courseInfo.getSignStart() > now) {
                                    //还没有到签到时间
                                    continue;
                                }
                                if (courseInfo.getEndTime() < now) {
                                    //已过签到时间
                                    continue;
                                }
                                boolean exsitTag = false;
                                List<ClassInfo> classInfoList = courseInfo.getClassInfoList();
                                for (ClassInfo classInfo : classInfoList) {
                                    if (classInfo.getClassId() == classId) {
                                        exsitTag = true;
                                        break;
                                    }
                                }
                                if (!exsitTag) {
                                    continue;
                                }
                                final SignInInfo signInInfo = new SignInInfo();
                                //签到成功
                                if (courseInfo.getSignEnd() > now) {
                                    //正点或运行迟到范围内
                                    if (courseInfo.getStartTime() < now) {
                                        //迟到
                                        signTag = 2;
                                        signInInfo.setRemark("迟到" + (now - courseInfo.getStartTime()) / 60000 + "分钟");
                                    } else {
                                        signTag = 1;
                                    }
                                    USBSerialManager.getInstence().sendCtrlSerialCode("attendancereader", "FE 01 03 00 ED 06 D4 D6 FF FF");
                                } else {
                                    //迟到视为旷课
                                    signTag = 3;
                                    signInInfo.setRemark("迟到" + (now - courseInfo.getStartTime()) / 60000 + "分钟视为旷课");
                                    USBSerialManager.getInstence().sendCtrlSerialCode("attendancereader", "FE 01 03 00 ED 08 55 12 FF FF");
                                }
                                //保存签到记录
                                signInInfo.setUploadTag(0);
                                signInInfo.setCourseInfo(JSON.toJSONString(courseInfo));
                                signInInfo.setStudentInfo(JSON.toJSONString(studentInfo));
                                signInInfo.setSignTag(signTag);
                                signInInfo.setSignTime(TimeUtil.getCurTimeToString("yyyy-MM-dd HH:mm:ss"));
                                signInInfo.setIdTag(System.currentTimeMillis() + "");
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            DbUtil.getInstance().save(signInInfo);
                                        } catch (DbException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }).start();

                                break;
                            }
                            if (signTag < 0) {
                                USBSerialManager.getInstence().sendCtrlSerialCode("attendancereader", "FE 01 03 00 ED 07 15 16 FF FF");
                            }
                        }
                    } else {
                        //签到失败，课程不匹配
                        USBSerialManager.getInstence().sendCtrlSerialCode("attendancereader", "FE 01 03 00 ED 07 15 16 FF FF");
                    }
                } catch (DbException e) {
                    e.printStackTrace();
                    USBSerialManager.getInstence().sendSerialMessageFromPort("attendancereader", true, "FE 01 03 00 ED 07 15 16 FF FF");
                }
            }
        }).start();

    }


    private String parseKeyName(int keyCode) {
        String code = null;
        if (keyCode >= 7 && keyCode <= 16) {
            code = String.valueOf(keyCode - 7);
        }
        return code;
    }
}
